package net;

import net.buffer.IntPack;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

public class NetServer{

    private ServerSocket serverSocket;
    private final int port;
    private List<NetClient> clients;
    private Consumer<NetClient> handler;

    public NetServer(int port)
    {
        this.port = port;
        clients = new ArrayList<>();
    }

    public void start()
    {
        try {
            serverSocket = new ServerSocket(port);
            System.out.println("ServerSocket Start with " + port);
            startAccept();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void setAcceptHandler(Consumer<NetClient> handler)
    {
        this.handler = handler;
    }

    void startAccept()
    {
        CompletableFuture.runAsync(()->{
            try {
                Socket socket = serverSocket.accept();
                NetClient client = new NetClient(socket,new IntPack(15), 2000);
                clients.add(client);
                client.statusHandler(this::clientStatusChange);
                if(handler!= null) handler.accept(client);
                client.start();
                startAccept();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }, PoolExecutor.executor());
    }

    private void clientStatusChange(NetClient client)
    {
        switch (client.status())
        {
            case NetStatus.DISCONNECTED -> {
                System.out.println("client closed");
            }
            case NetStatus.TIMEOUT -> System.out.println("client timeout");
            case NetStatus.CLOSED -> {
                System.out.println("client CLOSED");
                clients.remove(client);
            }
        }
    }
}
